package com.sun.servlet;

import com.alibaba.fastjson.JSON;
import com.sun.dao.BookDao;
import com.sun.dao.BorrowDao;
import com.sun.dao.FineDao;
import com.sun.dao.ReaderDao;
import com.sun.domain.Book;
import com.sun.domain.Borrow;
import com.sun.domain.Fine;
import com.sun.domain.Reader;
import com.sun.util.BorrowUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * @author SunRui
 * @description borrow servlet
 * @date 2024/7/4 21:07
 */
@WebServlet(urlPatterns = "/BorrowServlet.action")
public class BorrowServlet extends HttpServlet {
    private static Logger logger = Logger.getLogger(ReaderServlet.class);
    InputStream resource = Resources.getResourceAsStream("mybatisConfig.xml");
    //获取session工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resource);

    public BorrowServlet() throws IOException {
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取session会话对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        BorrowDao borrowDao = sqlSession.getMapper(BorrowDao.class);
        BookDao bookDao = sqlSession.getMapper(BookDao.class);
        ReaderDao readerDao = sqlSession.getMapper(ReaderDao.class);
        FineDao fineDao = sqlSession.getMapper(FineDao.class);
        Fine fine;
        String opr = req.getParameter("opr");
        String jsonString = null;
        HttpSession session = req.getSession();
        String str = null;
        BorrowUtil borrowUtil = new BorrowUtil();
        switch (opr) {
            case "borrowBookTs":
                //借阅
                //接收传回要借阅的暂存架图书code
                String elBookTs = req.getParameter("bookIds");
                elBookTs = elBookTs.substring(1, elBookTs.length() - 1);
                String[] eliminateBookTs = elBookTs.split(",");
                List<String> elBootTsId = new ArrayList<>();
                for (String bookId : eliminateBookTs) {
                    elBootTsId.add(bookId.replace("\"", ""));
                }
                logger.debug("借阅书籍code:" + elBootTsId);
                //获取借阅人ID
                Reader reader = (Reader) session.getAttribute("reader");
                int readerId = reader.getId();
                //查看借阅人是否还剩足够的借阅数借阅图书
                if (readerDao.selectBorrowSum(readerId)>=elBootTsId.size()){
                    if (readerDao.deductBorrowSum(readerId,elBootTsId.size())>0){
                        List<Book> bookList = new ArrayList<>();
                        for (String bookCode : elBootTsId) {
                            //通过code返回书籍信息
                            Book book = bookDao.bookTs(bookCode);
                            bookList.add(book);
                        }
                        logger.debug("借阅书籍信息:" + bookList.toString());
                        List<Borrow> borrowList = new ArrayList<>();
                        for (Book book : bookList) {
                            Borrow borrow = new Borrow();
                            String borrowDate = borrowUtil.getCurrentDate();
                            borrow.setBorrowDate(borrowDate);
                            borrow.setBookId(book.getId());
                            borrow.setReaderId(readerId);
                            borrowList.add(borrow);
                            //更改书籍状态
                            bookDao.setBookSatus(book.getId(), 2);
                        }
                        if (borrowDao.addBorrow(borrowList) > 0) {
                            try {
                                //提交事务
                                sqlSession.commit();
                                logger.debug("注册事务:提交成功");
                            } catch (Exception e) {
                                e.printStackTrace();
                                logger.debug("注册事务:提交失败(" + e.getMessage() + ")");
                                //回滚(出错了回滚)
                                sqlSession.rollback();
                            }
                            //获取缓存架数据进行清除操作
                            List<String> eliminateCodeArray = (List<String>) session.getAttribute("codeArray");
                            logger.debug("elBootTsId:" + elBootTsId.toString());
                            logger.debug("eliminateCodeArray:" + eliminateCodeArray.toString());
                            if (eliminateCodeArray != null) {
                                for (String bookId : elBootTsId) {
                                    if (eliminateCodeArray.contains(bookId)) {
                                        eliminateCodeArray.remove(bookId);
                                    }
                                }
                                session.setAttribute("codeArray", eliminateCodeArray);
                                str = "ok";
                            }
                        }
                        logger.debug("清除结束(codeArray)：" + (List<String>) session.getAttribute("codeArray"));
                    }
                }else {
                    str = "noBookNum";
                }

                sqlSession.close();
                jsonString = JSON.toJSONString(str);
                resp.getWriter().write(jsonString);
                break;
            case "borrowBookTsShow":
                //加载借阅架
                //获取借阅人ID
                Reader reader2 = (Reader) session.getAttribute("reader");
                int readerId2 = reader2.getId();
                List<Borrow> borrows = borrowDao.getBorrow(readerId2, 0);
                for (Borrow b : borrows) {
                    int bookId = b.getBookId();
                    Book book = bookDao.getBook(bookId);
                    b.setBookName(book.getName());
                }
                sqlSession.close();
                jsonString = JSON.toJSONString(borrows);
                resp.getWriter().write(jsonString);
                break;
            case "borrowBookTsOne":
                // 借阅1本书
                String code = req.getParameter("code");
                //获取借阅人ID
                Reader reader3 = (Reader) session.getAttribute("reader");
                int readerId3 = reader3.getId();
                if (readerDao.selectBorrowSum(readerId3)>=1){
                    readerDao.deductBorrowSum(readerId3,1);
                    List<Book> bookList1 = new ArrayList<>();
                    //通过code返回书籍信息
                    Book book = bookDao.bookTs(code);
                    bookList1.add(book);
                    logger.debug("借阅书籍信息:" + bookList1.toString());
                    List<Borrow> borrowList1 = new ArrayList<>();
                    for (Book book1 : bookList1) {
                        Borrow borrow = new Borrow();
                        String borrowDate = borrowUtil.getCurrentDate();
                        borrow.setBorrowDate(borrowDate);
                        borrow.setBookId(book1.getId());
                        borrow.setReaderId(readerId3);
                        borrowList1.add(borrow);
                        //更改书籍状态
                        bookDao.setBookSatus(book.getId(), 2);
                    }
                    if (borrowDao.addBorrow(borrowList1) > 0) {
                        try {
                            //提交事务
                            sqlSession.commit();
                            logger.debug("注册事务:提交成功");
                        } catch (Exception e) {
                            e.printStackTrace();
                            logger.debug("注册事务:提交失败(" + e.getMessage() + ")");
                            //回滚(出错了回滚)
                            sqlSession.rollback();
                        }
                        //获取缓存架数据进行清除操作
                        List<String> eliminateCodeArray = (List<String>) session.getAttribute("codeArray");
                        if (eliminateCodeArray == null) {
                            eliminateCodeArray = new ArrayList<>();
                        }
                        logger.debug("OneCode:" + code);
                        logger.debug("eliminateCodeArray:" + eliminateCodeArray.toString());

                        if (eliminateCodeArray != null) {
                            if (eliminateCodeArray.contains(code)) {
                                eliminateCodeArray.remove(code);
                            }
                            session.setAttribute("codeArray", eliminateCodeArray);
                            str = "ok";
                        }
                    }
                    logger.debug("清除结束(codeArray)：" + (List<String>) session.getAttribute("codeArray"));
                }else {
                    str = "noBookNum";
                }

                sqlSession.close();
                jsonString = JSON.toJSONString(str);
                resp.getWriter().write(jsonString);
                break;
            case "borrowRenew":
                int borrowId = Integer.parseInt(req.getParameter("borrowId"));
                int renewDays = Integer.parseInt(req.getParameter("renewDay"));
                logger.debug("续借ID："+borrowId+"续借天数："+renewDays);
                if (borrowDao.updateRenewDays(renewDays,borrowId)>0){
                    str = "ok";
                    try {
                        //提交事务
                        sqlSession.commit();
                        logger.debug("注册事务:提交成功");
                    } catch (Exception e) {
                        e.printStackTrace();
                        logger.debug("注册事务:提交失败(" + e.getMessage() + ")");
                        //回滚(出错了回滚)
                        sqlSession.rollback();
                    }
                }
                sqlSession.close();
                jsonString = JSON.toJSONString(str);
                resp.getWriter().write(jsonString);
                break;
            case "returnBook":
                // 还书
                // 通过传回的ID查询借阅信息
                int borrowIds = Integer.parseInt(req.getParameter("borrowId"));
                logger.debug("还书的ID:"+borrowIds);
                Borrow returnBorrow = borrowDao.getBorrowById(borrowIds);
                logger.debug("归还书的信息:"+returnBorrow.toString());
                Reader reader5 = (Reader) session.getAttribute("reader");
                int readerId5 = reader5.getId();
                //将借阅天数和续借天数相加，查看是否超过时间需要还款
                int borrowDays = returnBorrow.getBorrowDays();
                int renewDays2 = returnBorrow.getRenewDays();
                String borrowDate = returnBorrow.getBorrowDate();
                int totalDays = borrowDays + renewDays2;
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                LocalDateTime borrowDateObj = LocalDateTime.parse(borrowDate, formatter);
                LocalDateTime dueDate = borrowDateObj.plusDays(totalDays);
                LocalDateTime now = LocalDateTime.now();
                int bookId = returnBorrow.getBookId();
                //将bookId和borrowIds存储到Session方便还款的时候调用
                session.setAttribute("fineAmountBookId",bookId);
                session.setAttribute("fineAmountBorrowIds",borrowIds);
                if (dueDate.isAfter(now)) {
                    System.out.println("未超过还款日期");
                    //将书籍状态改成在库,并将归还状态改成1
                    borrowDao.updateBack(borrowIds);
                    bookDao.setBookSatus(bookId,1);
                    //将可借阅书籍数量+1
                    readerDao.addBorrowSum(readerId5,1);
                    try {
                        //提交事务
                        sqlSession.commit();
                        logger.debug("注册事务:提交成功");
                    } catch (Exception e) {
                        e.printStackTrace();
                        logger.debug("注册事务:提交失败(" + e.getMessage() + ")");
                        //回滚(出错了回滚)
                        sqlSession.rollback();
                    }
                    str = "ok";//还书成功
                } else {
                    logger.debug("ID:"+borrowIds+"超过还款日期，需要罚款！");
                    //计算罚款金额
                    float fineAmount = 0;
                    try {
                        logger.debug("借书日期："+dueDate.format(formatter)+";结束日期："+ now.format(formatter));
                        fineAmount = borrowUtil.calculateFine(now.format(formatter),dueDate.format(formatter));
                    } catch (ParseException e) {
                        logger.debug(e);
                    }
                    logger.debug("罚款金额:"+fineAmount);
                    //将罚款金额先暂时存储到Session中
                    session.setAttribute("fineAmount", fineAmount);

                    str = "因为超出还书日期，需缴纳罚款："+fineAmount;
                }
                sqlSession.close();
                jsonString = JSON.toJSONString(str);
                resp.getWriter().write(jsonString);
                break;
            case "fineAmount":
                // 还款
                float fineAmounts = (float) session.getAttribute("fineAmount");
                logger.debug("需要还款金额："+fineAmounts);
                // 获取当前用户有多少钱
                Reader reader4 = (Reader) session.getAttribute("reader");
                float money = reader4.getMoney();
                //从session中提取数据进行还书
                int fineAmountBookId = (int) session.getAttribute("fineAmountBookId");
                int fineAmountBorrowIds = (int) session.getAttribute("fineAmountBorrowIds");
                if (money >= fineAmounts){
                    logger.debug("用户的金额大于等于需要还款的金额");
                    //进行扣钱操作
                    readerDao.updateMoney(fineAmounts,reader4.getId());
                    //进行增加可借阅书数量操作
                    readerDao.addBorrowSum(reader4.getId(),1);
                    //将书籍状态改成在库,并将归还状态改成1
                    borrowDao.updateBack(fineAmountBorrowIds);
                    bookDao.setBookSatus(fineAmountBookId,1);
                    //添加罚款记录
                    fine = new Fine();
                    fine.setBorrowId(fineAmountBorrowIds);
                    fine.setReaderId(reader4.getId());
                    fine.setBookId(fineAmountBookId);
                    fine.setAmount(fineAmounts);
                    DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    LocalDateTime now2 = LocalDateTime.now();
                    fine.setPaidDate(now2.format(formatter2));
                    fine.setStaus(1);
                    fineDao.addFine(fine);
                    try {
                        //提交事务
                        sqlSession.commit();
                        logger.debug("注册事务:提交成功");
                    } catch (Exception e) {
                        e.printStackTrace();
                        logger.debug("注册事务:提交失败(" + e.getMessage() + ")");
                        //回滚(出错了回滚)
                        sqlSession.rollback();
                    }
                    str = "ok";//还书成功
                }else {
                    logger.debug("用户的金额远远达不到还款金额");
                    str = "no";
                }
                sqlSession.close();
                jsonString = JSON.toJSONString(str);
                resp.getWriter().write(jsonString);
                break;
            case "borrowHistoryTabShow":
                //借阅历史查询
                Reader reader1 = (Reader) session.getAttribute("reader");
                int page = Integer.parseInt(req.getParameter("page"));
                List<com.sun.domain.BorrowUtil> borrowUtils = borrowDao.getBorrowUtilList(reader1.getId(),((page-1)*5));
                sqlSession.close();
                jsonString = JSON.toJSONString(borrowUtils);
                resp.getWriter().write(jsonString);
                break;
            case "borrowHistoryPageShow":
                //获取借阅历史查询的总页数
                //获取总页数
                reader = (Reader) session.getAttribute("reader");
                readerId = reader.getId();
                int allPage = borrowDao.getAllPage(readerId);
                int pages;
                if (allPage%5>0){
                    pages = (allPage/5)+1;
                }else {
                    pages = allPage/5;
                }
                sqlSession.close();
                jsonString = JSON.toJSONString(pages);
                resp.getWriter().write(jsonString);
                break;
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }

}
